/**
 * Copyright(c) 2013-2015 by Puhuifinance Inc.
 * All Rights Reserved
 */
package com.puhui.chome.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.puhui.chome.manager.MonitorCcManager;
import com.puhui.chome.manager.MonitorItemManager;
import com.puhui.chome.manager.MonitorSystemManager;
import com.puhui.chome.model.MonitorCc;
import com.puhui.chome.model.MonitorItem;
import com.puhui.chome.model.MonitorSystem;
import com.puhui.chome.service.MonitorItemService;
import com.puhui.chome.util.EmailMessageInfo;
import com.puhui.chome.util.JdbcUtil;
import com.puhui.chome.util.SendEmail;

/**
 * @author dingxingang
 */
@Service
public class MonitorItemServiceImpl implements MonitorItemService {

    private static final Logger logger = LoggerFactory.getLogger(MonitorItemServiceImpl.class);

    @Autowired
    private MonitorItemManager monitorItemManager;
    @Autowired
    private MonitorSystemManager monitorSystemManager;
    @Autowired
    private MonitorCcManager monitorCcManager;

    /**
     * 添加
     */
    @Override
    public void addMonitorItem(MonitorItem monitorItem) {
        monitorItemManager.addMonitorItem(monitorItem);
    }

    /**
     * 获取
     */
    @Override
    public MonitorItem getMonitorItemById(Long id) {
        return monitorItemManager.getMonitorItemById(id);
    }

    /**
     * 查询总记录数
     */
    @Override
    public long findMonitorItemCount(Map<String, Object> param) {
        return monitorItemManager.findMonitorItemCount(param);
    }

    /**
     * 查询列表
     */
    @Override
    public List<MonitorItem> findMonitorItem(Map<String, Object> param) {
        return monitorItemManager.findMonitorItem(param);
    }

    /**
     * 定时监控
     * 
     * @author dingxingang
     * @param minute
     *            分钟数
     */
    @Override
    public void monitor(int minute) {
        if (minute == 0) {
            return;
        }
        // 根据当前时间分钟查询待监控项
        List<MonitorItem> list = monitorItemManager.findMonitorItemByExecuteMinute(minute);
        for (MonitorItem item : list) {
            try {
                monitorItem(item);
            } catch (Exception e) {
                logger.error("监控异常,编号[" + item.getId() + "],监控项[" + item.getName() + "]" + e.getMessage(), e);
            }
        }
        JdbcUtil.claseConn();
    }

    /**
     * 监控某监控项处理
     * 
     * @author dingxingang
     * @param item
     */
    @Override
    public void monitorItem(MonitorItem item) {
        logger.info("开始执行，监控项：{}", item.getName());
        // 获取系统信息,拼装报警内容
        MonitorSystem system = monitorSystemManager.getMonitorSystemById(item.getSystemId());
        JdbcUtil.URL = "jdbc:mysql://" + system.getDbUrl() + "/" + system.getDbName();
        JdbcUtil.DB_NAME = system.getDbUsername();
        JdbcUtil.DB_PASS = system.getDbPassword();
        Long count = JdbcUtil.queryDataCount(item.getMonitorScript());
        if (count == null) {
            logger.error("监控执行异常：" + item.getName());
            String content = "系统【" + system.getName() + "】编号【" + item.getId() + "】监控项【" + item.getName()
                    + "】监控执行异常，请检查监控脚本";
            sendMonitorMail(system.getEmail(), content, new ArrayList<MonitorCc>());
            item.setAlarm(true); // 警报
            monitorItemManager.updateMonitorItem(item);
            return;
        }
        // 根据阈值类型，判断是否报警0：大于；1：小于；2：大于等于；3：小于等
        boolean isError;
        switch (item.getThresholdType()) {
            case 1:
                isError = count < item.getThreshold();
                break;
            case 2:
                isError = count >= item.getThreshold();
                break;
            case 3:
                isError = count <= item.getThreshold();
                break;
            default:
                isError = count > item.getThreshold();
                break;
        }
        if (isError) {
            // 发送报警邮件
            logger.info("发送报警邮件！{}", count);
            String content = "系统【" + system.getName() + "】编号【" + item.getId() + "】监控项【" + item.getName() + "】报警数据量【"
                    + count + "】";
            // 获取监控项抄送列表
            List<MonitorCc> ccList = monitorCcManager.findMonitorCcByItemId(item.getId());
            // 首次报警发送邮件
            if (!item.getAlarm()) {
                sendMonitorMail(system.getEmail(), content, ccList);
            }
            logger.info("报警！超出阈值[{}]！查询数据量：{}", item.getThreshold(), count);
            // 更新警报状态
            item.setAlarm(true); // 警报
            monitorItemManager.updateMonitorItem(item);
        } else {
            item.setAlarm(false); // 正常
            monitorItemManager.updateMonitorItem(item);
        }
    }

    /**
     * 发送监控邮件
     * 
     * @author dingxingang
     * @param recipient
     * @param content
     * @return
     */
    private boolean sendMonitorMail(String recipient, String content, List<MonitorCc> ccList) {
        logger.info("发送内容：{}", content);
        EmailMessageInfo info = new EmailMessageInfo();
        info.setSubject(content);
        info.setBody(content);
        info.setHtml(true);
        info.setFromName("CHome监控系统"); // 发件人（姓名）
        info.addRecipient(recipient); // 收件地址
        logger.info("发送到：{}", recipient);
        // 监控抄送人
        for (MonitorCc cc : ccList) {
            logger.info("抄送：" + cc.getEmail());
            info.addCc(cc.getEmail()); // 抄送邮箱
        }
        try {
            // 发送邮件
            String message = SendEmail.httpPostSendMail(info);
            if ("OK".equals(message)) {
                return true;
            }
        } catch (Exception e) {
            logger.error("发送监控邮件异常：" + e.getMessage(), e);
            return false;
        }
        return true;
    }

    /**
     * 修改监控
     * 
     * @author dingxingang
     * @param monitorItem
     * @return
     */
    public int updateMonitorItem(MonitorItem monitorItem) {
        return monitorItemManager.updateMonitorItem(monitorItem);
    }

}
